package com.czh.codesandbox.utils;

import com.czh.codesandbox.model.ExecMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

import java.io.*;

/*
 * ClassName: ProcessUtils
 * Package: com.czh.codesandbox.utils
 * Description:
 *              工具类，用于执行进程，获取进程的返回值
 * @Author: CZH
 * @Create: 2025
 */
@Slf4j
public class ProcessUtils {
    /**
     *  执行进程，获取进程的返回值
     * @param process
     * @param opName
     * @return
     */
    public static ExecMessage getProcessReturnMessage(Process process,String opName) {
        ExecMessage execMessage = new ExecMessage();
        try {
            //等待进程结束,获取执行码
            int execValue = process.waitFor();
            execMessage.setExitValue(execValue);
            //通过进程结束后返回的执行码execValue，来判断编译是否成功
            if(execValue == 0){
                System.out.println(opName + "成功");
                // 创建BufferedReader对象，读取正常执行的进程的输出流
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                StringBuilder outputStringBuilder = new StringBuilder();
                // 逐行读取输出流
                String outLine;
                while((outLine = bufferedReader.readLine()) != null){
                    outputStringBuilder.append(outLine);
                }
                execMessage.setMessage(outputStringBuilder.toString());
            }else{
                // 进程执行异常就退出
                System.out.println(opName + "失败，错误码：" + execValue);
                // 创建BufferedReader对象，读取正常执行的进程的输出流
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                StringBuilder outputStringBuilder = new StringBuilder();
                // 逐行读取输出流
                String outLine;
                while((outLine = bufferedReader.readLine()) != null){
                    outputStringBuilder.append(outLine);
                }
                execMessage.setMessage(outputStringBuilder.toString());

                // 创建BufferedReader对象，读取异常执行的进程的错误流
                BufferedReader erroBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                StringBuilder erroroutputStringBuilder = new StringBuilder();
                // 逐行读取错误流
                String errorOutputLine;
                while((errorOutputLine = erroBufferedReader.readLine()) != null){
                    erroroutputStringBuilder.append(errorOutputLine);
                }
                execMessage.setErrormessage(erroroutputStringBuilder.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return execMessage;
    }
    /**
     *  交互式执行进程，获取进程的返回值
     * @param process
     * @return
     */
    public static ExecMessage getInteractiveProcessReturnMessage(Process process,String args) {
        ExecMessage execMessage = new ExecMessage();
        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            // 向控制台输入
            OutputStream outputStream =  process.getOutputStream();
            // 创建输出流对象
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
            args.split(" ");
            String join = String.join("\n", args) + "\n";
            // 写入命令
            outputStreamWriter.write(join);
            // 相当于按下回车键，执行命令
            outputStreamWriter.flush();
            InputStream inputStream = process.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder outputStringBuilder = new StringBuilder();
            // 逐行读取输出流
            String outLine;
            while((outLine = bufferedReader.readLine()) != null){
                outputStringBuilder.append(outLine);
            }
            execMessage.setMessage(outputStringBuilder.toString());
            stopWatch.stop();
            execMessage.setTime(stopWatch.getTotalTimeMillis());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return execMessage;
    }
}
